package com.imay.videorecord.camera;

import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
import android.util.Log;

import com.imay.videorecord.camera.utils.CameraUtils;
import com.imay.videorecord.utils.ImayParams;

import java.io.IOException;
import java.util.List;

public class CameraEngine {
    private static Camera camera = null;
    private static int cameraID = 0;
    private static SurfaceTexture surfaceTexture;

    public static Camera getCamera() {
        return camera;
    }

    public static boolean openCamera() {
        if (camera == null) {
            try {
                CameraUtils.getCurrentScreenSize(1080, 1080);
                camera = Camera.open(cameraID);
                setDefaultParameters();
                return true;
            } catch (RuntimeException e) {
                return false;
            }
        }
        return false;
    }

    public static boolean openCamera(int id, int width, int height) {
        if (camera == null) {
            try {
                CameraUtils.getCurrentScreenSize(width, height);
                camera = Camera.open(id);
                cameraID = id;
                setDefaultParameters();
                return true;
            } catch (RuntimeException e) {
                return false;
            }
        }
        return false;
    }

    public static void releaseCamera() {
        if (camera != null) {
            camera.setPreviewCallback(null);
            camera.stopPreview();
            camera.release();
            camera = null;
        }
    }

    public static void pauceCamera() {
        if (camera != null) {
            camera.setPreviewCallback(null);
            camera.stopPreview();
        }
    }


    public static void setZoom(float scale) {
        if (isSupportZoom(camera)) {
            Parameters params = camera.getParameters();
            final int max = params.getMaxZoom();
            int min = 0;
            if (max == 0) return;
            int zoomValue = params.getZoom();
            if (zoomValue < 2 && scale < 0) { //缩小
                zoomValue = min;
            } else if (zoomValue == max && scale > 0) {
                zoomValue = max;
            } else {
                zoomValue += scale;
            }
            params.setZoom(zoomValue);
            camera.setParameters(params);
        } else {
            Log.d("ICCamera", "--------setZoom--------the phone not support zoom");
        }
    }

    public static boolean isSupportZoom(Camera camera) {
        if (camera == null) {
            return false;
        }
        boolean isSuppport = false;
        if (camera.getParameters().isZoomSupported()) { //&&camera.getParameters().isSmoothZoomSupported()
            isSuppport = true;
        }
        return isSuppport;
    }

    public static void setFlashMode(int flashMode) {
        if (camera == null) {
            return;
        }
        Parameters parameters = camera.getParameters();
        List<String> flashModes = parameters.getSupportedFlashModes();
        if (flashModes == null) {
            return;
        }
        if (flashMode == 0) {
            if (flashModes.contains(Parameters.FLASH_MODE_OFF)) {
                parameters.setFlashMode(Parameters.FLASH_MODE_OFF);//自动
                camera.setParameters(parameters);
            }
        } else if (flashMode == 1) {
            if (flashModes.contains(Parameters.FLASH_MODE_TORCH)) {
                parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
                camera.setParameters(parameters);
            }
        }
    }

    public static void resumeCamera(int surfaceWidth, int surfaceHeight) {
        openCamera(cameraID, surfaceWidth, surfaceHeight);
        startPreview(surfaceTexture);
    }

    public static boolean getCameraFrontStatus() {
        return cameraID == 0 ? true : false;
    }

    public void setParameters(Parameters parameters) {
        camera.setParameters(parameters);
    }

    public Parameters getParameters() {
        if (camera != null)
            camera.getParameters();
        return null;
    }

    public static void switchCamera(int w, int h) {
        releaseCamera();
        cameraID = cameraID == 0 ? 1 : 0;
        ImayParams.OPEN_CAMERA_ID = cameraID;
        openCamera(cameraID, w, h);
    }

    private static void setDefaultParameters() {
        if (camera == null) {
            return;
        }
        Parameters parameters = camera.getParameters();
        if (parameters.getSupportedFocusModes().contains(
                Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
            parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
        }

        CameraUtils.choosePreviewSize(parameters);

        CameraUtils.chooseFixedPreviewFps(parameters, 30000);

        parameters.setRecordingHint(true);

        parameters.setRotation(90);
        camera.setParameters(parameters);
    }

    private static Size getPreviewSize() {
        if (camera == null) {
            return null;
        }
        return camera.getParameters().getPreviewSize();
    }

    private static Size getPictureSize() {
        if (camera == null) {
            return null;
        }
        return camera.getParameters().getPictureSize();
    }

    public static void startPreview(SurfaceTexture surfaceTexture) {
        if (camera != null)
            try {
                camera.setPreviewTexture(surfaceTexture);
                CameraEngine.surfaceTexture = surfaceTexture;
                camera.startPreview();
            } catch (IOException e) {
                e.printStackTrace();
            }
    }

    public static void startPreview() {
        if (camera != null)
            camera.startPreview();
    }

    public static void stopPreview() {
        camera.stopPreview();
    }

    public static void setRotation(int rotation) {
        Camera.Parameters params = camera.getParameters();
        params.setRotation(rotation);
        camera.setParameters(params);
    }

    public static void takePicture(Camera.ShutterCallback shutterCallback, Camera.PictureCallback rawCallback,
                                   Camera.PictureCallback jpegCallback) {
        camera.takePicture(shutterCallback, rawCallback, jpegCallback);
    }

    public static com.imay.videorecord.camera.utils.CameraInfo getCameraInfo() {
        com.imay.videorecord.camera.utils.CameraInfo info = new com.imay.videorecord.camera.utils.CameraInfo();
        Size size = getPreviewSize();
        if (size == null) {
            return null;
        }
        CameraInfo cameraInfo = new CameraInfo();
        Camera.getCameraInfo(cameraID, cameraInfo);
        info.previewWidth = size.width;
        info.previewHeight = size.height;
        info.orientation = cameraInfo.orientation;
        info.isFront = cameraID == 1 ? true : false;
        return info;
    }

    public static void onDestroy() {
        Log.d("Camera", "cameraID=" + cameraID);
        releaseCamera();
        cameraID = 0;
        if (surfaceTexture != null) {
            surfaceTexture.release();
            surfaceTexture = null;
        }
    }
}